//
//
//
//
//  Created by wulanzhou on 16-3-7.
//  Copyright (c) 2016年 . All rights reserved.
//

#import "WBRequestArgs.h"
#import "WBConfigHandler.h"
//soap 1.1请求方式
#define defaultSoap1Message @"<?xml version=\"1.0\" encoding=\"utf-8\"?><soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">%@<soap:Body>%@</soap:Body></soap:Envelope>"
//soap 1.2请求方式
#define defaultSoap12Message @"<?xml version=\"1.0\" encoding=\"utf-8\"?><soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">%@<soap12:Body>%@</soap12:Body></soap12:Envelope>"

@interface WBRequestArgs()
{
    NSString *requestKey_;
    NSMutableDictionary *postDataDic_;
}
@property (nonatomic,readonly) NSString *hostName;
-(NSString*)stringSoapMessage:(NSArray*)params;
-(NSString*)paramsFormatString:(NSArray*)params;
-(NSString*)soapAction:(NSString*)namespace methodName:(NSString*)methodName;
-(NSString*)paramsTostring;
@end



@implementation WBRequestArgs
@synthesize postParams=postDataDic_;
@synthesize requestKey=requestKey_;

-(id)init{
    if (self=[super init]) {
        self.httpWay=ASIServiceHttpSoap1;
        self.defaultEncoding=NSUTF8StringEncoding;
        self.timeOutSeconds=25.0f;
        
        
        WBRequestConfig *config=[WBConfigHandler shareRequestConfig];
        self.serviceURL=config.httpServer;
        self.serviceNameSpace=config.nameSpace;
        
         postDataDic_=[NSMutableDictionary dictionaryWithCapacity:0];
    }
    return self;
}

#pragma mark -
#pragma mark 属性重写
- (NSString*)requestKey{
    if (requestKey_&&[requestKey_ length]>0) {
        return requestKey_;
    }
    NSString *key = [NSString stringWithFormat:@"%@_%@",
                     self.methodName,[self createGUID]];
    
    requestKey_=key;
    return requestKey_;
}
-(NSString*)defaultSoapMesage{
    if (self.httpWay==ASIServiceHttpSoap1) {
        return defaultSoap1Message;
    }
    return defaultSoap12Message;
}
-(NSURL*)webURL{
    return [NSURL URLWithString:[self serviceURL]];
}
- (void)setHttpWay:(WBServiceHttpWay)way{
    if (way!=_httpWay) {
        self.bodyMessage=@"";
        self.headers=nil;
    }
    _httpWay=way;
}
/***
-(NSString*)bodyMessage{
    if (self.httpWay==ASIServiceHttpGet) {
        return @"";
    }
    if (_bodyMessage&&[_bodyMessage length]>0) {
        return _bodyMessage;
    }
    if (self.httpWay==ASIServiceHttpPost) {
        return [self paramsTostring];
    }
    return [self stringSoapMessage:[self soapParams]];
}
 ***/
- (NSString*)requestBodyMessage{
    if (self.httpWay==ASIServiceHttpGet) {
        return @"";
    }
    if (_bodyMessage&&[_bodyMessage length]>0) {
        return _bodyMessage;
    }
    if (self.httpWay==ASIServiceHttpPost) {
        return [self paramsTostring];
    }
    return [self stringSoapMessage:[self soapParams]];
}
- (NSString*)hostName{
    NSURL *webURL=[self requestURL];
    if (webURL.port) {
        return [NSString stringWithFormat:@"%@:%d",webURL.host,[webURL.port intValue]];
    }
    return [webURL host];
}
-(NSDictionary*)headers{
    if (_headers&&[_headers count]>0) {
        return _headers;
    }
    if (self.httpWay==ASIServiceHttpGet) {
        return [NSMutableDictionary dictionaryWithObjectsAndKeys:[self hostName],@"Host", nil];
    }
    NSMutableDictionary *dic=[NSMutableDictionary dictionary];
    [dic setValue:[self hostName] forKey:@"Host"];
    if (self.httpWay==ASIServiceHttpPost) {
        [dic setValue:@"application/x-www-form-urlencoded" forKey:@"Content-Type"];
    }
    if (self.httpWay==ASIServiceHttpSoap1) {
        [dic setValue:@"text/xml; charset=utf-8" forKey:@"Content-Type"];
    }
    if (self.httpWay==ASIServiceHttpSoap12) {
        [dic setValue:@"application/soap+xml; charset=utf-8" forKey:@"Content-Type"];
    }
    [dic setValue:[NSString stringWithFormat:@"%d",(int)[[self requestBodyMessage] length]] forKey:@"Content-Length"];
    if (self.httpWay==ASIServiceHttpSoap1) {
        NSString *soapAction=[self soapAction:[self serviceNameSpace] methodName:[self methodName]];
        if ([soapAction length]>0) {
            [dic setValue:soapAction forKey:@"SOAPAction"];
        }
    }
    NSLog(@"请求头为:%@",dic);
    return dic;
}
- (AFHTTPRequestOperation*)request{
    
    NSMutableURLRequest *req=[NSMutableURLRequest requestWithURL:[self requestURL]];
    //头部设置
    [req setAllHTTPHeaderFields:[self headers]];
    //超时设置
    [req setTimeoutInterval:self.timeOutSeconds];
    //访问方式
    [req setHTTPMethod:self.httpWay==ASIServiceHttpGet?@"GET":@"POST"];
    //body内容
    if (self.httpWay!=ASIServiceHttpGet) {
        [req setHTTPBody:[[self requestBodyMessage] dataUsingEncoding:self.defaultEncoding]];
    }
    
    NSLog(@"请求参数 =%@",[self requestBodyMessage]);

    AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:req];
    //op.responseSerializer = [AFXMLParserResponseSerializer serializer];
    op.responseSerializer = [AFHTTPResponseSerializer serializer];//响应
    return op;
    
}
#pragma mark -
#pragma mark 公有方法
-(NSString*)stringSoapMessage:(NSArray*)params{
    
    NSString *startNode=self.httpWay==ASIServiceHttpSoap1?@"<soap:Header>":@"<soap12:Header>";
    NSString *endNode=self.httpWay==ASIServiceHttpSoap1?@"</soap:Header>":@"</soap12:Header>";
    
    NSString *header=_soapHeader&&[_soapHeader length]>0?[NSString stringWithFormat:@"%@%@%@",startNode,_soapHeader,endNode]:@"";
    NSString *xmlnsStr=[[self serviceNameSpace] length]>0?[NSString stringWithFormat:@" xmlns=\"%@\"",[self serviceNameSpace]]:@"";
    
    if ([postDataDic_ count]>0) {
        NSMutableString *soap=[NSMutableString stringWithFormat:@"<%@%@>",[self methodName],xmlnsStr];
        
        for (NSString *key in postDataDic_) {
            
            [soap appendFormat:@"<%@>",key];
            [soap appendString:[postDataDic_ objectForKey:key]];
            [soap appendFormat:@"</%@>",key];
        }
        
        //[soap appendString:[self paramsFormatString:params]];
        [soap appendFormat:@"</%@>",[self methodName]];
        return [NSString stringWithFormat:[self defaultSoapMesage],header,soap];
    }
    NSString *body=[NSString stringWithFormat:@"<%@%@ />",[self methodName],xmlnsStr];
    return [NSString stringWithFormat:[self defaultSoapMesage],header,body];
}
+(WBRequestArgs*)serviceMethodName:(NSString*)methodName{
    return [self serviceMethodName:methodName soapMessage:nil];
}
+(WBRequestArgs*)serviceMethodName:(NSString*)name soapMessage:(NSString*)msg{
    WBRequestArgs *args=[[WBRequestArgs alloc] init];
    args.methodName=name;
    if (msg&&[msg length]>0) {
        args.bodyMessage=msg;
    }else{
        args.bodyMessage=[args stringSoapMessage:nil];
    }
    return args;
}
#pragma mark -
#pragma mark 私有方法
/**
 *  基于参数(data=)封装
 *
 *  @param firstObject 可变参数 key与value组成
 */
-(void)paramWithObjectsAndKeys:(NSString*)firstObject, ... NS_REQUIRES_NIL_TERMINATION{
    NSMutableArray *values=[NSMutableArray arrayWithCapacity:0];
    NSMutableArray *keys=[NSMutableArray arrayWithCapacity:0];
    NSInteger index=0;
    va_list args;
    va_start(args,firstObject);
    if(firstObject)
    {
        [values addObject:firstObject];
        index++;
        NSString *otherString;
        while((otherString=va_arg(args,NSString*)))
        {
            if (index%2==0){
                [values addObject:otherString];
            }else{
                //依次取得所有参数
                [keys addObject:otherString];
            }
            index++;
        }
    }
    va_end(args);
    
    NSAssert([values count]==[keys count], @"paramWithObjectsAndKeys方法设置的key与value不匹配!");
    
    if([keys count]>0&&[values count]>0)
    {
        for(NSInteger i=0;i<[values count];i++)
        {
            [self setParamValue:[values objectAtIndex:i] name:[keys objectAtIndex:i]];
        }
    }
}

/**
 *  一次性设置所有请求参数
 *
 *  @param params 请求参数 key与value组成
 */
-(void)addParamWithDictionary:(NSDictionary*)params{
    if(params&&[params count]>0){
        [postDataDic_ addEntriesFromDictionary:params];
        
    }
}
/**
 *  基于参数(data=)封装
 *
 *  @param value 参数值
 *  @param key   参数名
 */
- (void)setParamValue:(NSString*)value name:(NSString*)key{
    //[self.postParams addObject:[NSString stringWithFormat:@"%@/%@",key,[self encodeToPercentEscapeString:value]]];
    //[self.postParams addObject:[NSString stringWithFormat:@"%@=%@",key,value]];
    [postDataDic_ setValue:value forKey:key];
}
-(NSURL*)requestURL{
    if (self.httpWay==ASIServiceHttpSoap1||self.httpWay==ASIServiceHttpSoap12) {
        return [self webURL];
    }
    if (self.httpWay==ASIServiceHttpGet) {
        NSString *params=[self paramsTostring];
        NSString *str=[params length]>0?[NSString stringWithFormat:@"?%@",params]:@"";
        NSString *result=[NSString stringWithFormat:@"%@/%@%@",[self serviceURL],[self methodName],str];
        return [NSURL URLWithString:result];
    }
    return [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@",[self serviceURL],[self methodName]]];
}
-(NSString*)paramsTostring
{
    NSArray *arr=[self soapParams];
    if (arr&&[arr count]>0) {
        NSMutableArray *results=[NSMutableArray array];
        for (NSDictionary *item in arr) {
            NSString *key=[[item allKeys] objectAtIndex:0];
            [results addObject:[NSString stringWithFormat:@"%@=%@",key,[item objectForKey:key]]];
        }
        return [results componentsJoinedByString:@"&"];
    }
    return @"";
}
-(NSString*)paramsFormatString:(NSArray*)params{
    NSMutableString *xml=[NSMutableString stringWithFormat:@""];
    for (NSDictionary *item in params) {
        NSString *key=[[item allKeys] objectAtIndex:0];
        [xml appendFormat:@"<%@>",key];
        [xml appendString:[item objectForKey:key]];
        [xml appendFormat:@"</%@>",key];
    }
    return xml;
}
-(NSString*)soapAction:(NSString*)namespace methodName:(NSString*)methodName{
    if (namespace&&[namespace length]>0) {
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"/$" options:0 error:nil];
        NSUInteger numberOfMatches = [regex numberOfMatchesInString:namespace options:0 range:NSMakeRange(0, [namespace length])];
        //NSArray *array=[regex matchesInString:namespace options:0 range:NSMakeRange(0, [namespace length])];
        if(numberOfMatches>0){
            return [NSString stringWithFormat:@"%@%@",namespace,methodName];
        }
        return [NSString stringWithFormat:@"%@/%@",namespace,methodName];
    }
    return @"";
}
/**
 *  生成guid值
 *
 *  @return 返回guid值
 */
- (NSString*)createGUID{
    CFUUIDRef uuid_ref = CFUUIDCreate(NULL);
    CFStringRef uuid_string_ref= CFUUIDCreateString(NULL, uuid_ref);
    CFRelease(uuid_ref);
    NSString *uuid = [NSString stringWithString:(__bridge NSString*)uuid_string_ref];
    CFRelease(uuid_string_ref);
    return uuid;
}
@end
